<template>
  <t-dialog
    v-model:show="popupVisible"
    position="bottom"
    :close-on-click-overlay="false"
    class="comment-replies-popup"
    @click-overlay="onBeforeCloseReplyDialog"
  >
    <div
      ref="dialogContentRef"
      class="comment-replies-popup__body flex flex-col bg-white text-sm"
    >
      <div class="popup-title px-5 py-2 shadow-sm flex justify-between items-center">
        <!-- 评论回复 -->
        <div class="text-subtitle1 text-base">{{ qLangComment.commentReply }}</div>
        <!-- <tm-icon
          name="cross"
          class="text-base teld-color-gray"
          @click="onBeforeCloseReplyDialog"
        /> -->
        <t-icon name="close" @click="onBeforeCloseReplyDialog" style="font-size:20px" />
      </div>

      <div
        ref="scrollAreaRef"
        class="popup-body-scrollable overflow-y-auto flex-1 pb-5 w-full"
      >
        <!-- 评论详情 -->
        <div class="section-comment flex px-5 pt-3">
          <!-- 左侧头像 -->
          <div class="left-avatar mr-2" style="">
            <UserAvatar :image-url="dataItem.UserAvatar" />
          </div>

          <div class="flex-1 flex flex-col overflow-hidden">
            <!-- 评论顶部信息 -->
            <div class="flex justify-between teld-color-gray mb-3">
              <span class="teld-color-gray font-semibold">{{
                userNameDisplay
              }}</span>
              <!-- <span :title="comment.CommentTime">{{ comment.CommentTimeRelative }}</span> -->
            </div>

            <!-- 评论内容行 -->
            <div class="comment-content mb-2">
              <div
                v-if="!comment.IsDeleted"
                v-html="decodeURIComponent(comment.Content)"
                class="break-all"
                @click="onClickContent"
              ></div>
              <div v-else class="teld-color-gray">{{
                qLangComment.commentIsDeleted
              }}</div>
            </div>

            <!-- 附件 -->
            <section
              v-if="
                !comment.IsDeleted &&
                comment.Attachments &&
                comment.Attachments.length
              "
              class="attachments-section w-full"
              :class="[dense ? 'mb-1' : 'mb-2']"
            >
              <div
                v-for="attachment in comment.Attachments"
                :key="attachment.ID"
                class="attachment-file flex items-center"
                :class="[dense ? '' : 'py-1']"
                @click="onClickAttachment(attachment)"
              >
                <!-- 文件类型图标 -->
                <FileTypeIcon
                  :file-name="attachment.FileName"
                  class="w-6 h-6 mr-2"
                />
                <!-- 文件名 -->
                <div
                  class="flex-1 mr-2 truncate overflow-hidden"
                  :title="attachment.FileName"
                >
                  {{ attachment.FileName }}
                </div>
              </div>
            </section>

            <!-- 评论底部行 -->
            <div class="flex justify-between">
              <span :title="comment.CommentTime" class="teld-color-gray">{{
                comment.CommentTimeRelative
              }}</span>
              <div
                class="comment-operations flex justify-end mb-3"
                :class="[
                  disabled ? 'teld-color-lightgray' : 'teld-color-gray',
                ]"
              >
                <!-- 点赞 -->
                <div
                  class="comment-like flex cursor-pointer leading-5"
                  :class="[disabled ? 'cursor-not-allowed' : '']"
                  @click="onClickLike"
                >
                  <SvgHeartFilled v-show="comment.Liked" class="mr-1" />
                  <SvgHeart v-show="!comment.Liked" class="mr-1" />
                  <span class="">{{ comment.LikeCount || 0 }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="gap h-5 w-full teld-bg-color-gray"></div>

        <!-- 回复列表 -->
        <div class="section-reply-list">
          <div
            class="reply-count py-3 px-5 border-b border-solid border-gray-100"
          >
            <span class="bg-white w-full">
              <!-- {{ totalReplyCount }} 条回复 -->
              {{ qLangComment.funcReplyCount(totalReplyCount) }}
            </span>
          </div>
          <ReplyItem
            v-for="reply in replyList"
            :key="reply.ID"
            :data-item="reply"
            :is-comment-deleted="comment.IsDeleted"
            v-model:total="total"
            class="reply-item-in-comment-detail px-5 pt-3"
            @reply="onReplyToReply"
            @delete="onDeleteReply(reply)"
          />
        </div>
      </div>

      <!-- 输入&发布回复 -->
      <draft-editor
        ref="draftEditorRef"
        :visible="!isLoading && visible"
        :input-indicator="true"
        :placeholder="inputPlaceholder"
        :autoClearOnHidding="true"
        @comment="onReplyToComment"
      />

      <!-- <PersonnelInfoPopup
        v-model:visible="personnelInfoVisible"
        v-model:user-id="mentionedUserId"
      /> -->

      <!-- 大图查看 -->
      <t-image-preview
        ref="imagePreviewRef"
        v-model="currentImgSrc"
        :src-list="previewSrcList"
      ></t-image-preview>
    </div>
  </t-dialog>
</template>

<script>
// Components
import SvgHeart from '../../components/svg-icons/heart.vue';
import SvgHeartFilled from '../../components/svg-icons/heart-filled.vue';
import SvgStar from '../../components/svg-icons/star.vue';
import SvgStarFilled from '../../components/svg-icons/star-filled.vue';
import ReplyItem from '../reply-item/index.vue';
import DraftEditor from '../draft-editor/index.vue';
import UserAvatar from '../../components/user-avatar/index.vue';
import FileTypeIcon from '../../components/file-type-icon/index.vue';
// import PersonnelInfoPopup from '../personnel-info-popup/index.vue';

// Utils
import { scrollPaging, saveAs, checkDirty } from '../../hooks';
import {
  GetRepliesList,
  saveReply,
  turnOnLike,
  cancelLike,
} from '../../hooks/api';

/**
 * [移动端]评论详情，回复列表 Popup
 */
export default {
  name: 'CommentRepliesPopup',
  inject: [
    'qLangComment',
    'loginUserInfo',
    // 'pageUrl',
    'notificationLink',
  ],
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    /**
     * Comment数据条目
     */
    dataItem: {
      type: Object,
      default: () => {},
    },
  },
  components: {
    SvgHeart,
    SvgHeartFilled,
    SvgStar,
    SvgStarFilled,
    ReplyItem,
    DraftEditor,
    UserAvatar,
    FileTypeIcon,
    // PersonnelInfoPopup,
  },
  data() {
    return {
      disabled: false, // TODO 是否在评论详情中增加删除功能？
      comment: {},
      replyList: [],
      isLoading: false,
      hasLoadedAll: false,
      pageIndex: 1,
      pageSize: 20,
      totalReplyCount: 0,
      //
      personnelInfoVisible: false,
      mentionedUserId: null,
      //
      previewSrcList: [],
      currentImgSrc: '',
    };
  },
  watch: {
    visible(val) {
      if (val) {
        // dialog挂载时插槽内容没有加载，所以mountd时点不行
        setTimeout(() => {
          // 用延时确保插槽内容已挂载，再启动滚动监听
          const scrollArea = this.$refs.scrollAreaRef;
          if (scrollArea) {
            scrollArea.addEventListener('scroll', this.onScroll, true);
          }
          this.init();
        }, 300);
      } else {
        // 关闭后取消滚动监听
        const scrollArea = this.$refs.scrollAreaRef;
        scrollArea && scrollArea.removeEventListener('scroll', this.onScroll);
        this.reset();
      }
    },
  },
  computed: {
    popupVisible: {
      get() {
        return this.visible;
      },
      set(v) {
        this.$emit('update:visible', v);
      },
    },
    isAuthor() {
      const loginUser = this.loginUserInfo;
      return loginUser.userId === this.comment.UserID;
    },
    userNameDisplay() {
      return this.isAuthor ? '我' : this.comment.UserName;
    },
    inputPlaceholder() {
      return `回复 ${this.userNameDisplay}`;
    },
    total: {
      get() {
        return this.totalReplyCount;
      },
      set(val) {
        this.totalReplyCount = this.comment.ReplyCount = val;
        this.$emit('update:data-item', this.comment);
      },
    },
  },
  methods: {
    async fetchPageData() {
      this.isLoading = true;
      try {
        const payload = {
          CommentId: this.comment.ID,
          TargetID: '',
          PageIndex: this.pageIndex,
          PageCount: this.pageSize,
          Sort: 1, // 回复排序为正序
        };
        // const { data } = await this.$utils.sgApi.getDataAsync({
        //   url: this.$utils.common.getServiceUrl('CMTS-GetRepliesList'),
        //   data: { input: JSON.stringify(payload)}
        // }) || {};
        const res = await GetRepliesList(payload);

        if (!res || res.state !== '1' || !res.data) {
          // 获取数据失败
          return;
        }

        // 成功获取数据后
        const { Items, TotalCount } = res.data;
        this.replyList = this.replyList.concat(Items);
        this.total = TotalCount;
        this.pageIndex += 1;
        this.hasLoadedAll = this.replyList.length >= TotalCount;
      } catch (error) {
        console.log(error);
      } finally {
        setTimeout(() => {
          this.isLoading = false;
        }, 500);
      }
    },
    init() {
      // Mock for UI development
      // this.replyList = this.dataItem.Replies;
      // setTimeout(() => {
      //   this.isLoading = false;
      // }, 500);

      this.comment = { ...this.dataItem };
      // 获取评论的回复列表
      this.fetchPageData();
    },
    reset() {
      this.replyList = [];
      this.totalReplyCount = 0;
      this.pageIndex = 1;
    },
    async onClickLike() {
      if (this.disabled) return;
      const isLike = (this.comment.Liked = !this.comment.Liked);
      const diff = this.comment.Liked ? 1 : -1;
      this.comment.LikeCount += diff;
      let succeeded = false;

      const payload = isLike
        ? { CommentID: this.comment.ID, TargetID: 0 }
        : { Id: this.comment.ID };
      // const serviceCode = isLike ? 'CMTS-Like' : 'CMTS-CancelLike';
      const updateLikeState = isLike ? turnOnLike : cancelLike;
      try {
        // const { data } = await this.$utils.sgApi.getDataAsync({
        //   url: this.$utils.common.getServiceUrl(serviceCode),
        //   data: isLike ? { comment: JSON.stringify(payload) } : { input: JSON.stringify(payload) },
        // });
        const res = await updateLikeState(payload);

        if (res.state !== '1') {
          return;
        }

        succeeded = true;
        // this.$TM.Toast(isLike ? '已点赞' : '已取消点赞');
      } catch (error) {
        console.log(error);
      } finally {
        // 接口调用失败后，页面状态回滚
        if (!succeeded) {
          this.comment.Liked = !isLike;
          this.comment.LikeCount -= diff;
        }
      }
    },
    /**
     * 给回复发回复
     */
    onReplyToReply(data) {
      this.replyList.unshift(data);
      this.totalReplyCount += 1;
      this.comment.ReplyCount = this.totalReplyCount;
      this.$emit('reply');
    },
    /**
     * 给评论发回复
     */
    async onReplyToComment(draftInfo) {
      const loginUser = this.loginUserInfo;
      const { content, fileList, onSucceed, onFail } = draftInfo;
      const newCommentReply = {
        // 接口必传字段：
        CommentID: this.comment.ID,
        Content: content,
        UserAvatar: loginUser.avatar,
        // 回复给
        // RespondedUserID: this.comment.UserID,
        // RespondedUserName: this.comment.UserName,
        Attachments: fileList.map(n => n.result),
        Url: this.notificationLink(),
        UrlParams: JSON.stringify({
          // fpath: encodeURIComponent(this.pageUrl),
          showComment: true,
          commentId: this.comment.ID,
        }),
      };

      try {
        // const { data } = await this.$utils.sgApi.getDataAsync({
        //   url: this.$utils.common.getServiceUrl('CMTS-SaveReply'),
        //   data: { reply: JSON.stringify(newCommentReply)}
        // });
        const res = await saveReply(newCommentReply);
        console.log('onReplyToComment', res);

        if (!res || res.state !== '1' || !res.data) {
          onFail();
          return;
        }

        // mock new record, and override with real data
        Object.assign(
          newCommentReply,
          {
            ID: 'reply-reply-m-' + parseInt(Math.random() * 1000),
            ReplyTime: Date().toLocaleString(),
            UserID: loginUser.userId,
            UserName: loginUser.userName,
            Liked: false,
            LikeCount: 0,
            IsFavorite: false,
            FavoriteCount: 0,
            IsDeleted: false,
            CanCancel: true,
          },
          res.data,
        );

        // 调接口成功后清空输入框内容
        onSucceed();
        // 评论完将新添加评论展示出来
        this.replyList.unshift(newCommentReply);
        this.totalReplyCount += 1;
        this.comment.ReplyCount = this.totalReplyCount;
        this.$emit('reply');
      } catch (error) {
        console.log(error);
        onFail();
      }
    },
    onDeleteReply(replyItem) {
      this.totalReplyCount -= 1;
      this.$emit('delete-reply', replyItem);
    },
    onScroll(e) {
      const { deltaY } = e;
      console.log('onScroll', e);
      if (
        deltaY < 0 ||
        !this.replyList ||
        !this.replyList.length ||
        this.isLoading ||
        this.hasLoadedAll
      ) {
        // 滚向顶部时、没有数据时、正在加载数据时、及全部加载完时，滚动无需处理
        return;
      }
      requestAnimationFrame(this.scrollHanlder);
    },
    scrollHanlder() {
      const container = this.$refs.scrollAreaRef;
      const lastItem = container.querySelector(
        '.reply-item-in-comment-detail:last-child',
      );
      // 提前 200px 获取下一页数据
      scrollPaging(container, lastItem, 200, this.fetchPageData);
    },
    confirmClose() {
      this.reset();
      this.popupVisible = false;
    },
    /**
     * van-popup只有close和closed事件，并且不支持取消关闭
     * 因此需要自己实现关闭图标/按钮，在点击时自己才能控制关闭与否
     */
    onBeforeCloseReplyDialog() {
      // if (checkDirty(this.$refs.dialogContentRef)) {
      //   this.$TM.Dialog.confirm({
      //     title: '确认',
      //     message: '如果选择确定关闭，已编辑的内容都将被丢弃。',
      //     messageAlign: 'left',
      //     showCancelButton: true,
      //     closeOnClickOverlay: true,
      //     confirmButtonColor: 'var(--theme-color)',
      //   })
      //     .then(_ => {
      //       this.confirmClose();
      //     })
      //     .catch(_ => {
      //       // this.popupVisible = true;
      //     });
      // } else {
      //   this.confirmClose();
      // }
      this.confirmClose();
    },
    onClickContent(e) {
      const el = e.target;
      // 如果点击了图片，则放大查看
      if (el.nodeName === 'IMG' && el.currentSrc) {
        // this.$TM.ImagePreview({images:[el.currentSrc]});
        const previwer = this.$refs.imagePreviewRef;
        if (previwer) {
          previwer.open(el.currentSrc);
        }
      } else if (el.dataset.userId) {
        // 点击了提及人，则弹出人员信息
        this.mentionedUserId = el.dataset.userId;
        this.personnelInfoVisible = true;
      } else {
        // 点击了内容，则直接弹出回复框
        this.$refs.draftEditorRef.showInputPopup();
      }
    },
    handleDownloadFile(attachment) {
      const { AttachmentUrl, FileName } = attachment;
      saveAs({
        url: AttachmentUrl,
        fileName: FileName,
      });
    },
    onClickAttachment(attachment) {
      const ext = attachment.FileName.split('.').pop().toLowerCase();
      const previwer = this.$refs.imagePreviewRef;
      if (['png', 'jpg', 'jpeg', 'gif'].includes(ext) && previwer) {
        previwer.open(attachment.AttachmentUrl);
        return;
      }
      this.handleDownloadFile(attachment);
    },
  },
};
</script>

<style></style>
